/** 
    Copyright 2010 Henrik Andersson
    
    This file is part of Loopist.

    Loopist is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Loopist is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Loopist.  If not, see <http://www.gnu.org/licenses/>.
*/


package se.dinamic.loopist;
import android.util.Log;
import java.lang.Math;
import java.util.Random;
import java.nio.ShortBuffer;
import java.nio.FloatBuffer;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Bitmap;

public class Track {
	private static final int TRACK_COLORS[][]={{255,32,32},{32,255,32},{127,127,255},{255,255,32},{32,255,255}};
	private static int _trackCounter=0;
	private boolean _isRecording;
	private int _index;
	private int _trackNumber=0;
	private int _recordingFramePosition=0;
	
	private float _volume=1.0f;
	
	/** The track buffer */
	private ShortBuffer _track;
	
	/** The length of track in frames 44.1KHz */
	private int _frameCount;
	private Listener _listener;
	
	public static interface Listener {
		public void onWipe();
		public void onRecordPrepare();
		public void onPutSamples(ShortBuffer samples);
	}
	
	public Track(int frames) {
		_track=ShortBuffer.allocate(frames);
		_frameCount=frames;
		_trackNumber=_trackCounter;
		_trackCounter++;
	}
	
	public Track(Track reference) { 
		_frameCount = reference.getFrameCount();
		_track = ShortBuffer.allocate(_frameCount);
		
		_trackNumber=_trackCounter;
		_trackCounter++;
		
		// Fill track with noise for testingpurpos
		for(int i=0;i<_frameCount;i++)
			_track.put( (short)0 );
		
	}
	
	public void setListener( Listener listener) { _listener=listener; }
	/** Set the volume of the track... */
	public void setVolume( float volume ) {
		_volume=Math.min( Math.max(0.0f,volume) , 1.0f);
	}
	
	/** Get the volume of the track... */
	public float getVolume() { return _volume; }
	
	public boolean isRecording() { return _isRecording; }
	
	public void setRecording( boolean recording) {
		_isRecording = recording;
		if( _isRecording ) {
			wipe();
			_recordingFramePosition = 0;
			if(_listener != null) _listener.onRecordPrepare();
		} else {
			// Recording has stopped...
		}
	}
	
	public int getTrackNumber() { return _trackNumber; }
	
	public void merge(Track t) { }
	
	public void wipe() {
		synchronized(_track) {
			_track.clear();
			for(int i=0;i<_frameCount;i++)
				_track.put((short)0);
			_track.rewind();
			if( _listener != null ) _listener.onWipe( ) ;
		}
	}
	
	/** Check if current sample is at end of track... */
	public boolean isEndOfTrack() {
		if( _index == _frameCount-1 )
			return true;
		return false;
	}
	
	/** Get the color for the track. */
	public int[] getColor() {
		return TRACK_COLORS[_trackNumber];
	}
	
	
	public ShortBuffer getBuffer() { return _track; }
	public int getFrameCount() { return _frameCount; }
	
	/** Put buffer of samples into track at recording offset. */
	public void putSamples(ShortBuffer samples) {
		synchronized(_track) {
			samples.position(0);
			_track.mark();
			Log.v("Loopist","position "+ _recordingFramePosition );
			_track.position( _recordingFramePosition ); // Jump to recording position...
			
			if( _track.remaining() >= samples.capacity() )
				_track.put( samples ); 
			else {
				int rem=_track.remaining();
				for( int i=0;i<rem;i++)
					_track.put( samples.get() ); 
			}
			
			_recordingFramePosition = _track.position();
			_track.reset();
			
			if( _listener != null ) _listener.onPutSamples( samples ) ;
		}
	}
		
	public short getSample() { 
		synchronized(_track) { 
			_index=(_index+1)%_frameCount; 
			return (short)( _volume * _track.get(_index) ); 
		} 
	}	
}